package com.mask.im.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mask.im.business.common.model.IMSendMessage;
import com.mask.im.sdk.dto.IMPushMessage;
import com.mask.im.sdk.enums.MessagePushTypeEnum;
import com.mask.im.sdk.service.MessagePushService;
import com.mask.im.business.common.constant.MessageTypeConstant;
import com.mask.im.business.common.model.PageResult;
import com.mask.im.business.model.dto.*;
import com.mask.im.business.model.entity.chat.Friendships;
import com.mask.im.business.model.entity.chat.IMFriendChatMessageDO;
import com.mask.im.business.model.entity.chat.IMGroupChatMessageDO;
import com.mask.im.business.model.vo.IMFriendChatMessageVO;
import com.mask.im.business.model.entity.*;
import com.mask.im.business.common.exception.BusinessException;
import com.mask.im.business.mapper.*;
import com.mask.im.business.model.vo.RecommendVO;
import com.mask.im.business.common.model.RestResponse;
import com.mask.im.business.model.vo.TransferMoneyVO;
import com.mask.im.business.service.*;
import com.mask.im.business.common.util.PageUtil;
import com.mask.im.business.common.util.MaskIMSecurityUtils;
import com.mask.token.util.MaskSecurityUtil;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.SneakyThrows;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

import static com.mask.im.business.common.constant.CommonConstant.FALSE;
import static com.mask.im.business.common.constant.CommonConstant.TRUE;
import static com.mask.im.business.common.constant.WebSocketConstant.*;

/**
 * 好友聊天记录管理
 *
 * @author jian
 */
@Log4j2
@Service
public class IMFriendChatMessageServiceImpl extends ServiceImpl<IMFriendChatMessageMapper, IMFriendChatMessageDO> implements IMFriendChatMessageService {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private ChannelService channelService;

    @Autowired
    private UserAuthMapper userAuthMapper;

    @Autowired
    private IMGroupChatMessageMapper groupChatMessageMapper;

    @Autowired
    private FriendshipsService friendshipsService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserPurseMapper userPurseMapper;

    @Autowired
    private TransferHistoryMapper transferHistoryMapper;

    @Autowired
    private RedisService redisService;

    @Resource
    private IMFriendRelationService friendRelationService;
    @Resource
    private MessagePushService messageService;
    @Resource
    private IMChatListService chatListService;

    @Override
    public RestResponse<IMFriendChatMessageDO> sendMessage(FriendSendMessageDTO messageDTO) {
        //获取当前登录用户
        Long userId = MaskSecurityUtil.getCurrentUserId();
        if (null != userId) {
            //校验是否是我的好友
            Boolean isFriend = friendRelationService.isFriend(userId, messageDTO.getReceiverId());
//            if (isFriend) {
//                return RestResponse.fail("当前用户不是您的好友!");
//            }
            IMFriendChatMessageDO friendChatMessage = new IMFriendChatMessageDO();
            friendChatMessage.setTempId(messageDTO.getTempId());
            friendChatMessage.setSenderId(userId);
            friendChatMessage.setReceiverId(messageDTO.getReceiverId());
            friendChatMessage.setReceiverDeleted(Boolean.FALSE);
            friendChatMessage.setContent(messageDTO.getContent());
            friendChatMessage.setSenderDeleted(Boolean.FALSE);
            friendChatMessage.setMessageType(messageDTO.getMessageType());
            friendChatMessage.setCreateTime(new Date());
            friendChatMessage.setIsRead(Boolean.FALSE);
            friendChatMessage.setSendStatus(0);
            //根据消息类型存储对应的消息
            if (StringUtils.isNotBlank(messageDTO.getExtInfo())) {
                friendChatMessage.setExtInfo(messageDTO.getExtInfo());
            }
            //聊天记录入库
            this.baseMapper.insert(friendChatMessage);
            //在线推送到对应的客户中
            if (messageService.isOnline(messageDTO.getReceiverId())) {
                //推送消息到sdk
                IMPushMessage<IMFriendChatMessageDO> imPushMessage = new IMPushMessage<>();
                imPushMessage.setSenderId(userId);
                imPushMessage.setReceiverId(messageDTO.getReceiverId());
                imPushMessage.setPushType(MessagePushTypeEnum.FRIEND_MESSAGE.type());
                imPushMessage.setContent(friendChatMessage);
                Boolean pushedMessage = messageService.pushMessage(imPushMessage);
                if (pushedMessage) {
                    friendChatMessage.setSendStatus(1);
                    this.baseMapper.updateById(friendChatMessage);
                }
            }
            //异步推送到chatList最新消息中
            changeRecentAsync(friendChatMessage);
            return RestResponse.ok(friendChatMessage);
        }
        return RestResponse.fail(401, "用户未登录");
    }

    /**
     * 用于更新聊天记录最新消息和未读数量
     */
    @Async
    public void changeRecentAsync(IMFriendChatMessageDO friendChatMessageDO) {
        try {
            chatListService.updateChatLastMessage(friendChatMessageDO);
        } catch (Exception e) {
            log.error("更新好友最新消息异常，发送者: {}, 接收者: {}", friendChatMessageDO.getSenderId(), friendChatMessageDO.getReceiverId(), e);
            throw e;
        }
    }

    @Override
    public RestResponse<List<IMFriendChatMessageVO>> chatMessageList(Long friendId) {
        //获取登录用户
        Long userId = MaskSecurityUtil.getCurrentUserId();
        //获取当前当前登录用户
        UserInfo userInfo = userInfoMapper.selectById(userId);
        String myAvatar = userInfo.getAvatar();
        String myNickName = userInfo.getNickName();
        //获取好友信息
        UserInfo friendUserId = userInfoMapper.selectById(friendId);
        //获取好友备注
        Friendships friendships = friendshipsService.getOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userId).eq(Friendships::getTwoUserId, friendId));
        //获取发送的
        List<IMFriendChatMessageDO> imFriendChatMessages = this.baseMapper.selectChatMessages(userId, friendId, (int) PageUtil.getCurrentPage(), (int) PageUtil.getSize());
        List<IMFriendChatMessageVO> friendChatMessageDTOList = imFriendChatMessages.stream().map(item -> {
                    IMFriendChatMessageVO friendChatMessageDTO = new IMFriendChatMessageVO();
                    friendChatMessageDTO.setContent(item.getContent());
                    friendChatMessageDTO.setIsRetracted(item.getIsRetracted());
                    friendChatMessageDTO.setMessageType(item.getMessageType());
                    friendChatMessageDTO.setSendStatus(item.getSendStatus());
                    friendChatMessageDTO.setId(item.getId());
                    friendChatMessageDTO.setCreateTime(item.getCreateTime());
                    friendChatMessageDTO.setIsRead(item.getIsRead());
                    if (item.getSenderId().equals(userId)) {
                        friendChatMessageDTO.setSenderName(myNickName);
                        friendChatMessageDTO.setIsMyselfMsg(true);
                        friendChatMessageDTO.setSenderAvatar(myAvatar);
                        friendChatMessageDTO.setSenderId(item.getSenderId());
                        friendChatMessageDTO.setReceiveId(item.getReceiverId());
                    } else {
                        friendChatMessageDTO.setReceiveId(item.getSenderId());
                        friendChatMessageDTO.setIsMyselfMsg(false);
                        friendChatMessageDTO.setReceiveRemark(friendships.getRemark());
                        friendChatMessageDTO.setReceiveAvatar(friendUserId.getAvatar());
                    }
                    return friendChatMessageDTO;
                }).sorted(Comparator.comparing(IMFriendChatMessageVO::getCreateTime))
                .collect(Collectors.toList());
        return RestResponse.ok(friendChatMessageDTOList);
    }


    @Override
    public void saveChat(IMFriendChatMessageDO imFriendChatMessage) {
        this.baseMapper.insert(imFriendChatMessage);
    }


    @SneakyThrows
    @Override
    public RestResponse<List<FriendChatMessageDTO>> getChatMessageList(Long friendId) {
        Long userId = MaskSecurityUtil.getCurrentUserId();
        //获取自己信息
        UserInfo userInfo = userInfoMapper.selectById(userId);
        String myAvatar = userInfo.getAvatar();
        String myNickName = userInfo.getNickName();
        //获取好友信息
        UserInfo friendUserId = userInfoMapper.selectById(friendId);
        //获取好友备注
        Friendships friendships = friendshipsService.getOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userId).eq(Friendships::getTwoUserId, friendId));
        //获取发送的
        List<IMFriendChatMessageDO> imFriendChatMessages = this.baseMapper.selectChatMessages(userId, friendId, (int) PageUtil.getCurrentPage(), (int) PageUtil.getSize());
        List<FriendChatMessageDTO> friendChatMessageDTOList = imFriendChatMessages.stream().map(item -> {
                    FriendChatMessageDTO friendChatMessageDTO = new FriendChatMessageDTO();
                    friendChatMessageDTO.setContent(item.getContent());
                    friendChatMessageDTO.setIsRetracted(item.getIsRetracted());
                    friendChatMessageDTO.setMessageType(item.getMessageType());
                    friendChatMessageDTO.setSendStatus(item.getSendStatus());
                    friendChatMessageDTO.setId(item.getId());
                    friendChatMessageDTO.setCreateTime(item.getCreateTime());
                    friendChatMessageDTO.setIsRead(item.getIsRead());
                    if (item.getSenderId().equals(userId)) {
                        friendChatMessageDTO.setSenderName(myNickName);
                        friendChatMessageDTO.setIsMyselfMsg(true);
                        friendChatMessageDTO.setSenderAvatar(myAvatar);
                        friendChatMessageDTO.setSenderId(item.getSenderId());
                        friendChatMessageDTO.setReceiveId(item.getReceiverId());
                    } else {
                        friendChatMessageDTO.setReceiveId(item.getSenderId());
                        friendChatMessageDTO.setIsMyselfMsg(false);
                        friendChatMessageDTO.setReceiveRemark(friendships.getRemark());
                        friendChatMessageDTO.setReceiveAvatar(friendUserId.getAvatar());
                    }
                    return friendChatMessageDTO;
                }).sorted(Comparator.comparing(FriendChatMessageDTO::getCreateTime))
                .collect(Collectors.toList());
        return RestResponse.ok(friendChatMessageDTOList);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse<String> clearChatMessage(Long friendId) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        this.baseMapper.update(null, new LambdaUpdateWrapper<IMFriendChatMessageDO>()
                .set(IMFriendChatMessageDO::getSenderDeleted, 1)
                .eq(IMFriendChatMessageDO::getSenderId, userId)
                .eq(IMFriendChatMessageDO::getReceiverId, friendId));
        this.baseMapper.update(null, new LambdaUpdateWrapper<IMFriendChatMessageDO>()
                .set(IMFriendChatMessageDO::getReceiverDeleted, 1)
                .eq(IMFriendChatMessageDO::getReceiverId, userId)
                .eq(IMFriendChatMessageDO::getSenderId, friendId));
        return RestResponse.ok();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public RestResponse<Integer> deleteChatMessage(Integer chatId) {
        Long userInfoId = MaskIMSecurityUtils.getUseLongId();
        if (null == userInfoId) {
            throw new BusinessException("登录失效,请登录后操作!");
        }

        IMFriendChatMessageDO friendChatMessage = baseMapper.selectById(chatId);
        if (Objects.isNull(friendChatMessage)) {
            throw new BusinessException("删除失败");
        }

        Long fromUserId = friendChatMessage.getSenderId();
        Long toUserId = friendChatMessage.getReceiverId();

        if (userInfoId.equals(fromUserId)) {
            if (friendChatMessage.getSenderDeleted()) {
                throw new BusinessException("消息已被删除，请刷新页面");
            }
            friendChatMessage.setSenderDeleted(true);
        } else if (toUserId.equals(userInfoId)) {
            if (friendChatMessage.getReceiverDeleted()) {
                throw new BusinessException("消息已被删除，请刷新页面");
            }
            friendChatMessage.setReceiverDeleted(true);
        } else {
            throw new BusinessException("删除失败");
        }

        IMFriendChatMessageDO startMaxChatMessage = baseMapper.maxChatMessageId(userInfoId,
                friendChatMessage.getSenderId().equals(userInfoId) ? friendChatMessage.getReceiverId() : friendChatMessage.getSenderId());
        baseMapper.updateById(friendChatMessage);

        //TODO后更改最新消息
        IMFriendChatMessageDO lastMaxChatMessage = this.baseMapper.maxChatMessageId(userInfoId,
                friendChatMessage.getSenderId().equals(userInfoId) ? friendChatMessage.getReceiverId() : friendChatMessage.getSenderId());

        if (startMaxChatMessage.getId().equals(chatId)) {
            String lastMessage = null;
            if (lastMaxChatMessage != null) {
                lastMessage = lastMaxChatMessage.getIsRetracted().equals(FALSE) ?
                        lastMaxChatMessage.getContent() :
                        lastMaxChatMessage.getSenderId().equals(userInfoId) ? "您撤回了消息" : "对方撤回了消息";
            }
            friendshipsService.update(null, new LambdaUpdateWrapper<Friendships>()
                    .set(Friendships::getLatestNews, lastMessage)
                    .eq(Friendships::getOneUserId, userInfoId)
                    .eq(Friendships::getTwoUserId,
                            friendChatMessage.getSenderId().equals(userInfoId) ? friendChatMessage.getReceiverId() : friendChatMessage.getSenderId()));
            Channel userIdChannel = channelService.getUserIdChannel(userInfoId.toString());
            if (userIdChannel != null) {
                IMSendMessage websocketDTO = new IMSendMessage();
                websocketDTO.setCmd(30006);
                websocketDTO.setData(true);
                userIdChannel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(websocketDTO)));
            }
        }
        return RestResponse.ok(chatId);
    }

    @Override
    public RestResponse<String> sendRecommendFriends(RecommendVO recommendVO) {
        Long myId = MaskIMSecurityUtils.getUseLongId();
        List<String> userIds = Arrays.asList(recommendVO.getUserIds().split(","));
        userIds.forEach(id -> {
            Friendships friendships = friendshipsService.getOne(new LambdaQueryWrapper<Friendships>()
                    .eq(Friendships::getOneUserId, id)
                    .eq(Friendships::getTwoUserId, myId)
                    .eq(Friendships::getIsDelete, 0));
            int count = friendships == null ? 2 : friendships.getIsFriends();
            Channel friendChannel = channelService.getUserIdChannel(id);
            Channel myChannel = channelService.getUserIdChannel(myId.toString());
            Date sendTime = new Date();
            //保存聊天记录
            IMFriendChatMessageDO friendChatMessage = saveChatMessage(Long.valueOf(id), recommendVO.getRecommendFriendId(), myId, "个人名片", friendChannel, count, MessageTypeConstant.BUSINESS_CARD, sendTime);
            IMSendMessage websocketDTO = new IMSendMessage();
            FriendChatMessageDTO friendChatMessageDTO = friendshipsService.getChatMessageDTO(friendChatMessage);
            //封装消息
            websocketDTO.setData(friendChatMessageDTO);
            websocketDTO.setCmd(SINGLE_CHAT);
            //实时响应
            if (Objects.nonNull(friendChannel) && count == 1) {
                friendChannel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(websocketDTO)));
            }
            myChannel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(websocketDTO)));
            //异步刷新最新消息
            changeRecentNews(friendChannel, Long.valueOf(id), "个人名片", myId, 3, sendTime);
        });
        return RestResponse.ok();
    }

    @SneakyThrows
    @Override
    public PageResult<AdminChatMessageDTO> chatMessage(String sender, String receiver) {
        CompletableFuture<Integer> chatListCount = CompletableFuture.supplyAsync(() ->
                this.baseMapper.selectChatListCount(sender, receiver));
        List<AdminChatMessageDTO> chatListDTOList = this.baseMapper.selectChatList(sender, receiver,
                PageUtil.getCurrentPage(), PageUtil.getSize());
        return PageResult.<AdminChatMessageDTO>builder().data(chatListDTOList).total(chatListCount.get()).build();
    }

    @Override
    public RestResponse<String> viewContent(Integer id, String password, String type) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        UserAuth userAuth = userAuthMapper.selectOne(new LambdaQueryWrapper<UserAuth>()
                .select(UserAuth::getPassword)
                .eq(UserAuth::getUserInfoId, userId));
        if (!passwordEncoder.matches(password, userAuth.getPassword())) {
            return RestResponse.fail("密码错误");
        }
        if ("single".equals(type)) {
            IMFriendChatMessageDO friendChatMessage = this.baseMapper.selectById(id);
            return RestResponse.ok(friendChatMessage.getContent());
        }
        IMGroupChatMessageDO imGroupChatMessageDO1 = groupChatMessageMapper.selectById(id);
        return RestResponse.ok(imGroupChatMessageDO1.getContent());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public RestResponse<String> transferMoney(TransferMoneyVO transferMoneyVO) {
        checkTransferMoneySafe(transferMoneyVO);
        Long userId = MaskIMSecurityUtils.getUseLongId();
        //转账流水号
        String serialNumber = userId + String.valueOf(IdWorker.getId());
        //获取自己钱包信息
        UserPurse myUserPurse = userPurseMapper.selectOne(new LambdaUpdateWrapper<UserPurse>()
                .eq(UserPurse::getUserId, userId));
        //获取好友钱包信息
        UserPurse friendUserPurse = userPurseMapper.selectOne(new LambdaUpdateWrapper<UserPurse>()
                .eq(UserPurse::getUserId, transferMoneyVO.getFriendId()));
        //根据自己钱包版本号对自己金额进扣减
        userPurseMapper.update(null, new LambdaUpdateWrapper<UserPurse>()
                .set(UserPurse::getAmount, myUserPurse.getAmount().subtract(new BigDecimal(transferMoneyVO.getAmount())))
                .eq(UserPurse::getId, myUserPurse.getId())
                .eq(UserPurse::getVersion, myUserPurse.getVersion()));
        //根据好友钱包版本对金额进行增加
        userPurseMapper.update(null, new LambdaUpdateWrapper<UserPurse>()
                .set(UserPurse::getAmount, friendUserPurse.getAmount().add(new BigDecimal(transferMoneyVO.getAmount())))
                .eq(UserPurse::getId, friendUserPurse.getId())
                .eq(UserPurse::getVersion, friendUserPurse.getVersion()));
        //记入流水号
        TransferHistory transferHistory = TransferHistory.builder()
                .serialNumber(serialNumber)
                .acceptUserId(transferMoneyVO.getFriendId())
                .transferUserId(userId)
                .transferAmount(new BigDecimal(transferMoneyVO.getAmount()))
                .transferRemark(transferMoneyVO.getTransferRemark())
                .type("个人转账")
                .build();
        transferHistoryMapper.insert(transferHistory);

        //录入到聊天记录中
        Channel myChannel = channelService.getUserIdChannel(userId.toString());
        Channel friendChannel = channelService.getUserIdChannel(transferMoneyVO.getFriendId().toString());
        IMFriendChatMessageDO friendChatMessage = saveChatMessage(transferMoneyVO.getFriendId(), null, userId, String.valueOf(transferHistory.getId()), friendChannel, TRUE, 4, transferHistory.getCreateTime());
        IMSendMessage websocketDTO = new IMSendMessage();
        FriendChatMessageDTO friendChatMessageDTO = friendshipsService.getChatMessageDTO(friendChatMessage);
        //封装消息
        websocketDTO.setData(friendChatMessageDTO);
        websocketDTO.setCmd(SINGLE_CHAT);

        changeRecentNews(friendChannel, transferMoneyVO.getFriendId(), "转账", userId, 4, transferHistory.getCreateTime());
        //删除token
        redisService.hDel("face:check", transferMoneyVO.getToken() + userId);
        //实时响应
        if (Objects.nonNull(friendChannel)) {
            friendChannel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(websocketDTO)));
        }
        if (myChannel != null) {
            myChannel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(websocketDTO)));
        }
        return RestResponse.ok();
    }

    /**
     * 消息状态修改为已读
     *
     * @param messageReadDTO
     * @return
     */
    @Override
    public RestResponse<?> messageRead(MessageReadDTO messageReadDTO) {
        //获取登录信息
        Integer userId = MaskIMSecurityUtils.getUserId();
        int batched = baseMapper.batchUpdateReadStatus(messageReadDTO.getMessageIds(), userId, messageReadDTO.getFriendId(), 1, LocalDateTime.now());
        //校验更新的数量是否是前端传递的数量
        if (batched != messageReadDTO.getMessageIds().size()) {
            //记录更新失败日志

        }
        //TODO::更新会话表中的未读消息数量
        //更新Socket中的已读数据
        Channel userIdChannel = channelService.getUserIdChannel(messageReadDTO.getFriendId().toString());
        if (null != userIdChannel) {
            IMReadStatusNotifyDTO notifyDTO = new IMReadStatusNotifyDTO();
            notifyDTO.setReceiverId(userId);
            notifyDTO.setMessageIds(messageReadDTO.getMessageIds());
            notifyDTO.setReadTime(LocalDateTime.now());
            IMSendMessage imSendMessage = IMSendMessage.builder().cmd(30010).data(true).data("已读更新成功").data(notifyDTO).build();
            userIdChannel.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(imSendMessage)));

        }
        return RestResponse.ok();
    }


    @Override
    public IMFriendChatMessageDO getChatMessageById(Integer messageId) {
        return baseMapper.selectOne(new LambdaQueryWrapper<IMFriendChatMessageDO>().eq(IMFriendChatMessageDO::getId, messageId));
    }

    @Override
    public RestResponse<IMFriendChatMessageDO> retractMessage(Long id) {
        if (null != id) {
            IMFriendChatMessageDO messageDTO = this.baseMapper.selectById(id);
            Long userId = MaskSecurityUtil.getCurrentUserId();

            if (messageDTO.getIsRetracted()) {
                return RestResponse.fail("消息已经被撤回了");
            }

            if (!userId.equals(messageDTO.getSenderId())) {
                return RestResponse.fail("只能撤回自己的消息哦");
            }

            Date nowTime = new Date();
            long millisDiff = Math.abs(nowTime.getTime() - messageDTO.getCreateTime().getTime());
            // 取整（忽略秒）
            long until = millisDiff / (60 * 1000);
            if (Math.abs(until) >= 2) {
                return RestResponse.fail("消息超过两分钟不能再撤回");
            }
            messageDTO.setIsRetracted(true);
            messageDTO.setUpdateTime(new Date());
            baseMapper.updateById(messageDTO);
            //在线推送到对应的客户中
            if (messageService.isOnline(messageDTO.getReceiverId())) {
                //推送消息到sdk
                IMPushMessage<IMFriendChatMessageDO> imPushMessage = new IMPushMessage<>();
                imPushMessage.setSenderId(userId);
                imPushMessage.setReceiverId(messageDTO.getReceiverId());
                imPushMessage.setPushType("FRIEND");
                imPushMessage.setContent(messageDTO);
                messageService.pushMessage(imPushMessage);
            }
            //异步推送到chatList最新消息中
            changeRecentAsync(messageDTO);
            return RestResponse.ok(messageDTO);
        }
        return RestResponse.fail("消息id不能为空");
    }


    private IMFriendChatMessageDO saveChatMessage(Long receiverId, Long recommendId, Long userId, String content, Channel userIdChannel, int count, Integer messageType, Date sendTime) {
        IMFriendChatMessageDO imFriendChatMessage = IMFriendChatMessageDO.builder()
                .senderId(userId)
                .receiverId(receiverId)
                .content(content)
                .senderDeleted(false)
                .messageType(messageType)
                .sendStatus(count)
                .receiverDeleted(count != 1 ? true : false)
                .createTime(sendTime)
                .isRead(userIdChannel == null ? false : true)
                .build();
        baseMapper.insert(imFriendChatMessage);
        return imFriendChatMessage;
    }


    public void checkTransferMoneySafe(TransferMoneyVO transferMoneyVO) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        UserPurse userPurse = userPurseMapper.selectOne(new LambdaQueryWrapper<UserPurse>()
                .eq(UserPurse::getUserId, userId));
        if (userPurse.getAmount().compareTo(new BigDecimal(transferMoneyVO.getAmount())) < 0) {
            throw new BusinessException("金额不足！");
        }
        Object obj = redisService.hGet("face:check", transferMoneyVO.getToken() + userId);
        if (Objects.isNull(obj)) {
            throw new BusinessException("支付失败，请重新进行支付！");
        }
        Friendships friendships = friendshipsService.getOne(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userId)
                .eq(Friendships::getTwoUserId, transferMoneyVO.getFriendId())
                .eq(Friendships::getIsFriends, TRUE));
        if (Objects.isNull(friendships)) {
            throw new BusinessException("您还未添加对方为好友！");
        }
    }


    public void changeRecentNews(Channel channel, Long receiverId, String content, Long userId, Integer messageType, Date sendTime) {
        List<Friendships> friendships = friendshipsService.list(new LambdaQueryWrapper<Friendships>()
                .eq(Friendships::getOneUserId, userId).eq(Friendships::getTwoUserId, receiverId)
                .or()
                .eq(Friendships::getOneUserId, receiverId).eq(Friendships::getTwoUserId, userId));
        friendships.forEach(item -> {
            item.setLatestTime(sendTime);
            item.setMessageType(messageType);
            item.setLatestNews(content);
            item.setUnreadCount(Objects.isNull(channel) && !item.getOneUserId().equals(userId) ? item.getUnreadCount() + 1 : item.getUnreadCount());
            friendshipsService.saveOrUpdate(item);
        });
    }
}

